package cn.wetcland.urban.framework.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.wetcland.urban.common.MyAssert;
import cn.wetcland.urban.common.component.RedisCommonKey;
import cn.wetcland.urban.common.component.RedisComponent;
import cn.wetcland.urban.common.utils.CopyObjectUtil;
import cn.wetcland.urban.common.utils.bcrypt.BCryptPasswordEncoder;
import cn.wetcland.urban.framework.dto.CustomerChangePwdDTO;
import cn.wetcland.urban.framework.dto.CustomerLoginDTO;
import cn.wetcland.urban.framework.dto.CustomerRegisterDTO;
import cn.wetcland.urban.framework.mapper.UtCustomerMapper;
import cn.wetcland.urban.framework.mapper.UtDistrictMapper;
import cn.wetcland.urban.framework.mapper.UtFileUploadMapper;
import cn.wetcland.urban.framework.service.UtCustomerService;
import cn.wetcland.urban.framework.vo.CustomerLoginVO;
import cn.wetcland.urban.generator.domain.UtCustomer;
import cn.wetcland.urban.generator.domain.UtDistrict;
import cn.wetcland.urban.generator.domain.UtFileUpload;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.regex.Pattern;

/**
* @author Wetcland
* @description 针对表【ut_customer】的数据库操作Service实现
* @createDate 2024-01-21 09:51:59
*/
@Service
public class UtCustomerServiceImpl extends ServiceImpl<UtCustomerMapper, UtCustomer> implements UtCustomerService {

    @Resource
    public RedisComponent redisComponent;
    @Resource
    public UtCustomerMapper customerMapper;
    @Resource
    public UtFileUploadMapper fileUploadMapper;

    @Resource
    public UtDistrictMapper districtMapper;

    @Override
    public CustomerLoginVO handleCustomerLogin(CustomerLoginDTO loginDTO) {
        String s = redisComponent.get(RedisCommonKey.getRedisCommonVerifyCodeKey(loginDTO.getCodeKey()));
        MyAssert.notBlank(s, "codekey不存在");
        MyAssert.isTrue(s.trim().equalsIgnoreCase(loginDTO.getCode()), "验证码错误");
        redisComponent.delete(RedisCommonKey.getRedisCommonVerifyCodeKey(loginDTO.getCodeKey()));
        UtCustomer customer = customerMapper.selectOne(new QueryWrapper<UtCustomer>().eq("customer_username", loginDTO.getUsername()));
        MyAssert.notNull(customer, "该用户不存在");
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        boolean matches = bCryptPasswordEncoder.matches(loginDTO.getPassword(), customer.getCustomerPassword());
        MyAssert.isTrue(matches, "密码错误");
        StpUtil.login(customer.getCustomerId());
        return getCustomerLoginVO(customer);
    }

    @Override
    public void handleCustomerRegister(CustomerRegisterDTO registerDTO) {
        UtCustomer customer1 = customerMapper.selectOne(new QueryWrapper<UtCustomer>().eq("customer_username", registerDTO.getUsername()));
        MyAssert.isNull(customer1, "该用户名已被注册");

        UtCustomer phone = customerMapper.selectOne(new QueryWrapper<UtCustomer>().eq("phone", registerDTO.getPhone()));
        MyAssert.isNull(phone, "该手机号已被注册");

        MyAssert.isTrue(registerDTO.getPassword().equals(registerDTO.getConfirmPassword()), "密码与确认密码不一致");

        String s = redisComponent.get(RedisCommonKey.getRedisCommonVerifyCodeKey(registerDTO.getCodeKey()));
        MyAssert.notBlank(s, "codekey不存在");
        MyAssert.isTrue(s.trim().equalsIgnoreCase(registerDTO.getCode()), "验证码错误");
        redisComponent.delete(RedisCommonKey.getRedisCommonVerifyCodeKey(registerDTO.getCodeKey()));

        UtDistrict province = districtMapper.selectById(registerDTO.getProvinceId());
        UtDistrict city = districtMapper.selectById(registerDTO.getCityId());
        UtDistrict district = districtMapper.selectById(registerDTO.getDistrictId());
        MyAssert.isTrue(Objects.equals(city.getParentId(), province.getId()), "省市ID不对应");
        MyAssert.isTrue(Objects.equals(district.getParentId(), city.getId()), "市县ID不对应");
        MyAssert.isTrue(Pattern.matches("^1[3-9]\\d{9}$", registerDTO.getPhone()), "手机号格式错误");

        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        UtCustomer customer = new UtCustomer();
        customer.setCustomerPassword(bCryptPasswordEncoder.encode(registerDTO.getPassword()));
        customer.setCustomerUsername(registerDTO.getUsername());
        CopyObjectUtil.copyPropertiesIgnoreNull(registerDTO, customer);
        customerMapper.insert(customer);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleCustomerChangePwd(CustomerChangePwdDTO customerChangePwdDTO) {
        long loginIdAsLong = StpUtil.getLoginIdAsLong();
        MyAssert.isTrue(customerChangePwdDTO.getNewPwd().equals(customerChangePwdDTO.getConfirmNewPwd()), "新密码与确认密码不一致");
        UtCustomer utCustomer = customerMapper.selectById(loginIdAsLong);
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        boolean matches = bCryptPasswordEncoder.matches(customerChangePwdDTO.getOriginPwd(), utCustomer.getCustomerPassword());
        MyAssert.isTrue(matches, "原密码错误");
        utCustomer.setCustomerPassword(bCryptPasswordEncoder.encode(customerChangePwdDTO.getNewPwd()));
        customerMapper.updateById(utCustomer);
    }

    private CustomerLoginVO getCustomerLoginVO(UtCustomer customer) {
        CustomerLoginVO customerLoginVO = new CustomerLoginVO();
        customerLoginVO.setCustomerId(customer.getCustomerId());
        customerLoginVO.setCustomerUsername(customer.getCustomerUsername());
        customerLoginVO.setGender(customer.getGender());
        customerLoginVO.setPhone(customer.getPhone());
        customerLoginVO.setProvinceId(customer.getProvinceId());
        customerLoginVO.setCityId(customer.getCityId());
        customerLoginVO.setDistrictId(customer.getDistrictId());
        UtDistrict district = districtMapper.selectById(customer.getCityId());
        MyAssert.notNull(district, "用户省市区未选择");
        customerLoginVO.setAdcode(district.getAdcode());
        if (customer.getCustomerAvatarImgId() != null) {
            UtFileUpload utFileUpload = fileUploadMapper.selectById(customer.getCustomerAvatarImgId());
            if (utFileUpload != null)
                customerLoginVO.setCustomerAvatar(utFileUpload.getUrl());
        }
        customerLoginVO.setToken(StpUtil.getTokenValue());
        return customerLoginVO;
    }
}




